
package stratego.java.ssm.piece;

import java.awt.Image;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * <code>public abstract class Piece</code>
 * <p>
 * The class that represents the game piece. Provides standard functionality for all pieces, as well
 * as allows piece collision resolution, should two pieces be placed in the same location.
 * Subclasses are responsible for reporting what they are weak to. Piece images obtained from:
 * http://vector.gissen.nl/stratego.html
 * </p>
 * 
 * @author Mark Aligbe
 * 
 */
public abstract class Piece
{
	private int	         rank;
	public AtomicBoolean	backShowing;
	
	/**
	 * <code>public Piece(int rank)</code>
	 * <p>
	 * Constructs a new Piece object with the specified rank. The bomb and flag have a rank of 0. An
	 * empty location on the board has a rank of -2. A blocked location has a rank of -1.
	 * </p>
	 * 
	 * @param rank
	 */
	public Piece(int rank)
	{
		this.rank = rank;
		backShowing = new AtomicBoolean(false);
	}
	
	/**
	 * <code>public int getRank()</code>
	 * <p>
	 * Returns the integer rank of this piece.
	 * </p>
	 * 
	 * @return
	 */
	public int getRank()
	{
		return rank;
	}
	
	/**
	 * <code>public boolean isBomb()</code>
	 * <p>
	 * Identifies whether this piece is a bomb.
	 * </p>
	 * 
	 * @return True if this piece is a bomb. False otherwise.
	 */
	public abstract boolean isBomb();
	
	/**
	 * <code>public boolean isFlag()</code>
	 * <p>
	 * Identifies whether this piece is a flag.
	 * </p>
	 * 
	 * @return True if this piece is a flag. False otherwise.
	 */
	public abstract boolean isFlag();
	
	/**
	 * <code>public boolean isSpy()</code>
	 * <p>
	 * Identifies whether this piece is a spy.
	 * </p>
	 * 
	 * @return True if this piece is a spy. False otherwise.
	 */
	public abstract boolean isSpy();
	
	/**
	 * <code>public boolean isScout()</code>
	 * <p>
	 * Identifies whether this piece is a scout.
	 * </p>
	 * 
	 * @return True if this piece is a scout. False otherwise.
	 */
	public abstract boolean isScout();
	
	/**
	 * <code>public boolean isMiner()</code>
	 * <p>
	 * Identifies whether this piece is a miner.
	 * </p>
	 * 
	 * @return True if this piece is a miner. False otherwise.
	 */
	public abstract boolean isMiner();
	
	/**
	 * <code>public boolean isEmpty()</code>
	 * <p>
	 * Identifies whether this piece is an EmptyPiece.
	 * </p>
	 * 
	 * @return True if this piece is an EmptyPiece. False otherwise.
	 */
	public abstract boolean isEmpty();
	
	/**
	 * <code>public boolean isBlock()</code>
	 * <p>
	 * Identifies whether this piece is a BlockPiece.
	 * </p>
	 * 
	 * @return True if this piece is a BlockPiece. False otherwise.
	 */
	public abstract boolean isBlock();
	
	/**
	 * <code>public VolatileImage getImage()</code>
	 * <p>
	 * Returns the VolatileImage that represents this piece. If the return is null, the piece should
	 * not be drawn.
	 * </p>
	 * 
	 * @return The VolatileImage used to represent this piece. null returns are possible.
	 */
	public abstract Image getImage();
	
	/**
	 * <code>public void setImage(Image img)</code>
	 * <p>
	 * Gets the original image imported by this Piece when it was created.
	 * </p>
	 * 
	 * @param image
	 *            - The unmodified image read from the filesystem.
	 */
	public abstract Image getOriginalImage();
	
	/**
	 * <code>public Image getBack()</code>
	 * <p>
	 * Gets the back side of this piece.
	 * </p>
	 * 
	 * @return The image representing the back of this piece.
	 */
	public abstract Image getBack();
	
	@Override
	/**Returns the rank and name of this piece*/
	public abstract String toString();
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode()
	{
		final int prime = 11;
		int result = 1;
		result = prime * result + rank;
		result += prime * toString().hashCode();
		return result;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Piece))
			return false;
		Piece other = (Piece) obj;
		if (rank != other.rank)
			return false;
		if (!toString().equals(other.toString()))
			return false;
		return true;
	}
	
}
